package subjectlist;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class A如何求一个字符串的所有排列 {
    /**
     * 实现一个方法，当输入一个字符串时，要求输出这个字符串的所有排列。
     * 例如，输入字符串abc，要求输出由字符a、b、c所能排列出来的所有字符串：
     * abc,acb,bac,bca,cab,cba
     */

    public static void main(String[] args) {
        A如何求一个字符串的所有排列 a = new A如何求一个字符串的所有排列();
        String[] abcds = a.permutation("abc");
        Arrays.stream(abcds).forEach(System.out::println);
    }

    List<String> res = new LinkedList<>();
    char[] c;
    public String[] permutation(String s) {
        c = s.toCharArray();
        dfs(0);
        return res.toArray(new String[res.size()]);
    }
    public void dfs(int x) {
        //当遍历到最后一个字符的时候就
        if(x == c.length - 1) {
            // 添加排列方案
            res.add(String.valueOf(c));
            return;
        }
        HashSet<Character> set = new HashSet<>();
        for(int i = x; i < c.length; i++) {
            if(set.contains(c[i])){
                continue; // 重复，因此剪枝
            }
            set.add(c[i]);
            // 交换，将 c[i] 固定在第 x 位
            swap(i, x);
            // 开启固定第 x + 1 位字符
            dfs(x + 1);
            // 恢复交换
            swap(i, x);
        }
    }
    public void swap(int a, int b) {
        char tmp = c[a];
        c[a] = c[b];
        c[b] = tmp;
    }
}
